package query

import (
	"fmt"
	"path/filepath"
	"strings"

	"github.com/glennliao/apijson-go/consts"
	"github.com/glennliao/apijson-go/model"
	"github.com/glennliao/apijson-go/util"
)

const (
	L列表总数 = "[]/total"
)

type Y引用节点 struct {
	J节点 *J节点
}

func X新建引用节点(n *J节点) *Y引用节点 {
	return &Y引用节点{J节点: n}
}

func (r *Y引用节点) J解析() {
	当前节点 := r.J节点

	引用字符串 := 当前节点.J简单请求值
	if strings.HasPrefix(引用字符串, "/") { // 这里/开头是相对同级
		引用字符串 = filepath.Dir(当前节点.L路径) + 引用字符串
	}
	引用路径, 引用列 := util.X解析引用列(引用字符串)
	if 引用路径 == 当前节点.L路径 { // 不能依赖自身
		当前节点.C错误 = consts.X新建请求验证错误(fmt.Sprintf("node cannot ref self: (%s)", 引用路径))
		return
	}

	引用节点 := 当前节点.C查询上下文.L路径节点映射[引用路径]
	if 引用节点 == nil {
		当前节点.C错误 = consts.X新建请求验证错误(fmt.Sprintf(" node %s is nil, but ref by %s", 引用路径, 当前节点.L路径))
		return
	}

	当前节点.Y引用键映射 = make(map[string]J节点引用)

	if strings.HasSuffix(当前节点.J简单请求值, L列表总数) {
		S设置需要总数(引用节点)
	}

	当前节点.Y引用键映射[当前节点.J键] = J节点引用{
		Z字段: 引用列,
		J节点: 引用节点,
	}
}

func (r *Y引用节点) H获取数据() {
	当前节点 := r.J节点
	for _, 引用节点 := range 当前节点.Y引用键映射 {
		if strings.HasSuffix(引用节点.Z字段, consts.Z总数) {
			当前节点.Z总数 = 引用节点.J节点.Z总数
		} else {
			引用结果 := 引用节点.J节点.F返回值
			switch 引用结果.(type) {
			case model.Map:
				当前节点.F返回值 = 引用结果.(model.Map)[引用节点.Z字段]
			}
		}
	}
}

func (r *Y引用节点) C处理结果() {
	当前节点 := r.J节点
	if strings.HasSuffix(当前节点.J简单请求值, L列表总数) {
		当前节点.F返回值 = 当前节点.Z总数
	}
}

func (r *Y引用节点) J节点类型() int {
	return J节点类型引用
}
